<?php

namespace app\controllers\h5\uni;

use app\controllers\h5\base\H5Controller;

use app\controllers\pay\PayRefund;
use app\models\order\Order;
use app\models\SetExpressApi;
// use app\models\SetExpressApi as Model;
use app\models\ZRegion;
use app\util\Request;
use app\controllers\h5\uni\address\AddressTool;

/**
 * api接口请求规则:
 *  请求方式	POST
    参数格式	application/json
    字符编码	统一采用UTF-8字符编码
 *
 *
 * 您的警戒金额为：100.00元，可用余额不足以支付本次订单，
 * 请注意警戒金额；","result":"您的警戒金额为：100.00元，
 * 可用余额不足以支付本次订单，请注意警戒金额
 *
 * 所以要充值200
 *
 * Class ExpressApiController
 * @package app\controllers\h5\uni
 */
class ExpressApiController extends H5Controller
{
    private $url = 'https://api.yunyangwl.com/api/wuliu/openService';

    // 这个是基础接口测试环境
    // private $url = 'https://api.yunyangwl.com/api/sandbox/openService';

    /*
     * 检测渠道
     * CHECK_CHANNEL_INTELLECT
     *
     * 下单
     * ADD_BILL_INTELLECT
     *
     * 取消
     * CANCEL
     *
     * 查询轨迹
     * QUERY_TRANCE
     *
     * 查询订单详情
     * QUERY_BILL_INFO
     *
     */

    private function signature($appid, $appkey, $request_id, $timestamp)
    {

        $str = $appid . $request_id . $timestamp . $appkey;
        $sign = md5($str);

        return $sign;
    }

    // 这个是类似java的uuid
    private function uuid()
    {
        // return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        return sprintf( '%04x%04x%04x%04x%04x%04x%04x%04x',
            mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
            mt_rand( 0, 0xffff ),
            mt_rand( 0, 0x0fff ) | 0x4000,
            mt_rand( 0, 0x3fff ) | 0x8000,
            mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
        );
    }

    /**
     * 查询渠道
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionChannel()
    {
        $set = SetExpressApi::getLastOne();

        // java中用的是微秒
        $time = time() * 1000;

        $uuid = $this->uuid();
        $sign = $this->signature($set->appid, $set->appkey, $uuid, $time);

        // var_dump($uuid, $sign);exit;


        $params = [
            'serviceCode' => 'CHECK_CHANNEL_INTELLECT',
            'timeStamp' => $time,
            'requestId' => $uuid,
            'appid' => $set->appid,
            'sign' => $sign,
            'content' => [
                'channelTag' => '智能',
                'channelSubTag' => '申通',
                'sender' => '张三',
                'senderMobile' => '13788887777',
                'senderProvince' => '',
                'senderCity' => '',
                'senderCounty' => '',
                // 'senderTown' => '',
                'senderLocation' => '',
                // 'senderAddress' => '',
                'receiver' => '',
                'receiverMobile' => '',
                'receiveProvince' => '',
                'receiveCity' => '',
                // 'receiveCounty' => '',
                // 'receiveTown' => '',
                'receiveLocation' => '',
                // 'receiveAddress' => '',
                'weight' => 1,
                'packageCount' => 1,
                // 'insured' => 1,
                // 'vloumLong' => 1,
                // 'vloumWidth' => 1,
                // 'vloumHeight' => 1,
            ]
        ];

        $content = $this->post('content');
        $params['content'] = $content;

        $result = Request::json($this->url, json_encode($params));

        // var_dump($result);
        $result = json_decode($result, true);

        // var_dump($result);exit;

        // 删除菜鸟
        if(isset($result['result']) && is_array($result['result'])) {
            $temp = [];
            foreach ($result['result'] as $key => $value) {
                if (strpos($value['tagType'], '菜鸟') !== false) {
                    // unset($result['result'][$key]);
                    continue;
                }
                array_push($temp, $value);
            }
            $result['result'] = $temp;
        }

        // var_dump($result);exit;

        if ($result && $result['code'] == 1) {
            return $this->successEncode($result);
        } else {
            if (isset($result['message'])) {
                return $this->fail($result['message']);
            }
            return $this->fail('查询快递渠道失败!');
        }

    }

    /**
     * 下单
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionOrder()
    {
        $set = SetExpressApi::getLastOne();

        // java中用的是微秒
        $time = time() * 1000;

        $uuid = $this->uuid();
        $sign = $this->signature($set->appid, $set->appkey, $uuid, $time);

        // var_dump($uuid, $sign);exit;


        $params = [
            'serviceCode' => 'ADD_BILL_INTELLECT',
            'timeStamp' => $time,
            'requestId' => $uuid,
            'appid' => $set->appid,
            'sign' => $sign,
            'content' => [
                'channelTag' => '智能',
                'channelSubTag' => '申通',
                'sender' => '张三',
                'senderMobile' => '13788887777',
                'senderProvince' => '',
                'senderCity' => '',
                'senderCounty' => '',
                // 'senderTown' => '',
                'senderLocation' => '',
                // 'senderAddress' => '',
                'receiver' => '',
                'receiverMobile' => '',
                'receiveProvince' => '',
                'receiveCity' => '',
                // 'receiveCounty' => '',
                // 'receiveTown' => '',
                'receiveLocation' => '',
                // 'receiveAddress' => '',
                'weight' => 1,
                'packageCount' => 1,
                // 'insured' => 1,
                // 'vloumLong' => 1,
                // 'vloumWidth' => 1,
                // 'vloumHeight' => 1,
            ]
        ];

        $content = $this->post('content');
        $params['content'] = $content;


        $result = Request::json($this->url, json_encode($params));

        // var_dump($result);exit;

        $result = json_decode($result, true);
        if ($result && $result['code'] == 1) {
            return $this->successEncode($result);
        } else {
            if (isset($result['message'])) {
                return $this->fail($result['message']);
            }

            return $this->fail('下单失败!');
        }

    }

    /**
     * 取消
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionCancel()
    {
        $set = SetExpressApi::getLastOne();

        // java中用的是微秒
        $time = time() * 1000;

        $uuid = $this->uuid();
        $sign = $this->signature($set->appid, $set->appkey, $uuid, $time);

        $params = [
            'serviceCode' => 'CANCEL',
            'timeStamp' => $time,
            'requestId' => $uuid,
            'appid' => $set->appid,
            'sign' => $sign,
            'content' => [
                'waybill' => '',
                'shopbill' => '',
            ]
        ];

        $content = $this->post('content');
        $params['content'] = $content;


        $result = Request::json($this->url, json_encode($params));

        // var_dump($result);exit;

        $result = json_decode($result, true);

        // $result['code'] = 1;

        if ($result && $result['code'] == 1) {

            $order_id = $this->post('order_id');
            // 退款
            if (!PayRefund::refund($order_id)) {
                return $this->fail('退款失败!');
            }

            return $this->successEncode($result);
        } else {
            if (isset($result['message'])) {
                return $this->fail($result['message']);
            }
            return $this->fail('取消失败!');
        }

    }

    // 这个是下单失败, 退款操作
    public function actionRefund()
    {
        $order_id = $this->post('order_id');

        // var_dump($order_id);exit;
        $order = Order::findOne(['id' => $order_id]);
        if ($order && $order->status == Order::$statusMapping['REFUND']) {
            return $this->fail('此订单已经退款过了!');
        }

        if (!PayRefund::refund($order_id)) {
            return $this->fail('退款失败!');
        }

        return $this->success();
    }

    // 查询 详情
    public function actionOpen()
    {
        $set = SetExpressApi::getLastOne();

        // java中用的是微秒
        $time = time() * 1000;

        $uuid = $this->uuid();
        $sign = $this->signature($set->appid, $set->appkey, $uuid, $time);

        $params = [
            'serviceCode' => 'QUERY_BILL_INFO',
            'timeStamp' => $time,
            'requestId' => $uuid,
            'appid' => $set->appid,
            'sign' => $sign,
            'content' => [
                'waybill' => '',
                'shopbill' => '',
            ]
        ];

        $content = $this->post('content');
        $params['content'] = $content;


        $result = Request::json($this->url, json_encode($params));

        // var_dump($result);exit;

        $result = json_decode($result, true);
        if ($result && $result['code'] == 1) {
            return $this->successEncode($result);
        } else {
            if (isset($result['message'])) {
                return $this->fail($result['message']);
            }
            return $this->fail('查询失败!');
        }
    }

    /**
     * 查询 轨迹
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionQuery()
    {
        $set = SetExpressApi::getLastOne();

        // java中用的是微秒
        $time = time() * 1000;

        $uuid = $this->uuid();
        $sign = $this->signature($set->appid, $set->appkey, $uuid, $time);

        $params = [
            'serviceCode' => 'QUERY_TRANCE',
            'timeStamp' => $time,
            'requestId' => $uuid,
            'appid' => $set->appid,
            'sign' => $sign,
            'content' => [
                'waybill' => '',
                'shopbill' => '',
                'traceFormat' => 'obj',
            ]
        ];

        $content = $this->post('content');
        $params['content'] = $content;


        $result = Request::json($this->url, json_encode($params));

        // var_dump($result);exit;

        $result = json_decode($result, true);
        if ($result && $result['code'] == 1) {
            return $this->successEncode($result);
        } else {
            if (isset($result['message'])) {
                return $this->fail($result['message']);
            }
            return $this->fail('查询失败!');
        }

    }

    // 地址解析
    // 地址识别
    public function actionParseAddress()
    {

        // 生成数据
        $file = __DIR__ . '/address/data/data.json';
        if (!file_exists($file)) {
            $province = ZRegion::find()
                ->where(['p_code' => 0])
                ->asArray()
                ->all();

            foreach ($province as &$item) {
                $item['name_'] = mb_substr($item['name'], 0, 2);
                $item['children'] = ZRegion::find()
                    ->where(['p_code' => $item['code']])
                    ->asArray()
                    ->all();
                foreach ($item['children'] as &$city) {
                    $city['name_'] = mb_substr($city['name'], 0, 2);
                    $city['name__'] = mb_substr($city['name'], 0, 3);
                    $city['children'] = ZRegion::find()
                        ->where(['p_code' => $city['code']])
                        ->asArray()
                        ->all();
                    foreach ($city['children'] as &$area) {
                        $area['name_'] = mb_substr($area['name'], 0, 2);
                        $area['name__'] = mb_substr($area['name'], 0, 3);
                        $area['name___'] = mb_substr($area['name'], 0, 4);
                    }
                }
            }
            file_put_contents($file, json_encode($province));
            chmod($file, 0777);
        }




        // 生成数据
        /*$province = ZRegion::find()
            ->where(['p_code' => 0])
            ->asArray()
            ->all();

        $file = __DIR__ . '/address/data/data.json';
        foreach ($province as &$item) {
            $item['name_'] = mb_substr($item['name'], 0, 2);
            $item['children'] = ZRegion::find()
                ->where(['p_code' => $item['code']])
                ->asArray()
                ->all();
            foreach ($item['children'] as &$city) {
                $city['name_'] = mb_substr($city['name'], 0, 2);
                $city['name__'] = mb_substr($city['name'], 0, 3);
                $city['children'] = ZRegion::find()
                    ->where(['p_code' => $city['code']])
                    ->asArray()
                    ->all();
                foreach ($city['children'] as &$area) {
                    $area['name_'] = mb_substr($area['name'], 0, 2);
                    $area['name__'] = mb_substr($area['name'], 0, 3);
                    $area['name___'] = mb_substr($area['name'], 0, 4);
                }
            }
        }
        file_put_contents($file, json_encode($province));

        $data = file_get_contents($file);
        $data = json_decode($data, true);

        return $this->successEncode($data);*/

        // $string = '张三  广东深圳市龙华区龙华街道1980科技文化产业园3栋317       13800138000 518000 120113196808214821';
        // $string = '张三  深圳市龙华区龙华街道1980科技文化产业园3栋317       13800138000 518000 120113196808214821';
        // $string = '张三  龙华区龙华街道1980科技文化产业园3栋317       13800138000 518000 120113196808214821';

        // 错误地址
        // $string = '张三  x华ff区龙f街道1980科技文化产业园3栋317       13800138000 518000 120113196808214821';

        // 前端传过来的地址
        $string = $this->post('address', '');

        $string = str_replace('电话', '', $string);
        $string = str_replace('收件人', '', $string);
        $string = str_replace(':', '', $string);
        $string = str_replace('：', '', $string);

        // var_dump($string);exit;

        // 根据空格分隔 姓名, 电话, 地址
        $arr = preg_split('/\s+|,+|，+/', $string);
        // $arr = preg_split('/\s+|,+|，+|:|：/', $string);
        // var_dump($arr);exit;
        if (count($arr) < 3) {
            return $this->fail('请用空格分隔姓名 电话 地址');
        }

        // var_dump($arr);exit;

        // 默认姓名第1位
        $name = '';
        // $name = $arr[0];
        $mobile = '';
        $address = '';

        // var_dump($arr);exit;

        // 处理手机号
        foreach ($arr as $item) {
            if (preg_match('/^1[3-9]\d{9}$/', $item)) {
                $mobile = $item;
            }
        }
        if (!$mobile) {
            return $this->fail('请填写正确的手机号码!');
        }

        // var_dump($name, $mobile);exit;

        // 处理地址
        // $string = str_replace($name, '', $string);
        $string = str_replace($mobile, '', $string);
        $arr = preg_split('/\s+|,+|，+/', $string);
        // var_dump($string, $arr);exit;
        // $name = $arr[0];
        if (count($arr) > 0) {
            $name = $arr[0];
        }
        foreach ($arr as $item) {
            if (!$item || mb_strlen($item) == 0 || $item == '') {
                continue;
            }
            if (mb_strlen($item) < mb_strlen($name)) {
                $name = $item;
            }
        }

        // 这个有些名称和详细地址重复
        // $string = str_replace($name, '', $string);
        $address = preg_replace('/\s+|,+|，+/', '', $string);

        // var_dump($name, $mobile, $address);exit;


        // if (preg_match('/^\+?\d{10,13}$/', $arr[0])) {
        //     $mobile = $arr[0];
        //     // 这种删除可以改变下标
        //     array_splice($arr, 0, 1);
        // } else if (preg_match('/^\+?\d{10,13}$/', $arr[1])) {
        //     $mobile = $arr[1];
        //     array_splice($arr, 1, 1);
        // } else if (preg_match('/^\+?\d{10,13}$/', $arr[2])) {
        //     $mobile = $arr[2];
        //     array_splice($arr, 2, 1);
        // } else {
        //     return $this->fail('电话号码错误');
        // }
        //
        // // var_dump($arr);exit;
        // if (mb_strlen($arr[0]) <= 3) {
        //     $name = $arr[0];
        //     $address = $arr[1];
        // } else {
        //     if (mb_strlen($arr[0]) >= mb_strlen($arr[1])) {
        //         $address = $arr[0];
        //         $name = $arr[1];
        //     } else {
        //         $address = $arr[1];
        //         $name = $arr[0];
        //     }
        // }

        // var_dump($name, $mobile, $address);

        $result = AddressTool::parse($address);

        // var_dump(222,$result);exit;

        // 没有找到
        if (!$result) {
            $area = [
                'name' => '',
                'code' => 0,
            ];
            $city = [
                'name' => '',
                'code' => 0,
            ];
            $province = [
                'name' => '',
                'code' => 0,
            ];

            $result = AddressTool::_formatData($area, $city, $province, $address);
        }

        if ($result['province']['code'] == 0) {
            return $this->fail('信息太少, 至少需要填写区/县和详细地址, 无法识别, 请手动填写!');
        }

        // var_dump($result);exit;

        if (!$result['address']) {
            // return $this->fail('请输入详细地址!');
        }

        $result['name'] = $name;
        $result['mobile'] = $mobile;

        return $this->successEncode($result);
    }
}